<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
    "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta name="generator" content="AsciiDoc 8.5.2" />
<title>Gerrit Code Review - Superprojects subscribed to submodules updates</title>
<style type="text/css">
/* Debug borders */
p, li, dt, dd, div, pre, h1, h2, h3, h4, h5, h6 {
/*
  border: 1px solid red;
*/
}

body {
  margin: 1em 5% 1em 5%;
}

a {
  color: blue;
  text-decoration: underline;
}
a:visited {
  color: fuchsia;
}

em {
  font-style: italic;
  color: navy;
}

strong {
  font-weight: bold;
  color: #083194;
}

tt {
  color: navy;
}

h1, h2, h3, h4, h5, h6 {
  color: #527bbd;
  font-family: sans-serif;
  margin-top: 1.2em;
  margin-bottom: 0.5em;
  line-height: 1.3;
}

h1, h2, h3 {
  border-bottom: 2px solid silver;
}
h2 {
  padding-top: 0.5em;
}
h3 {
  float: left;
}
h3 + * {
  clear: left;
}

div.sectionbody {
  font-family: serif;
  margin-left: 0;
}

hr {
  border: 1px solid silver;
}

p {
  margin-top: 0.5em;
  margin-bottom: 0.5em;
}

ul, ol, li > p {
  margin-top: 0;
}

pre {
  padding: 0;
  margin: 0;
}

span#author {
  color: #527bbd;
  font-family: sans-serif;
  font-weight: bold;
  font-size: 1.1em;
}
span#email {
}
span#revnumber, span#revdate, span#revremark {
  font-family: sans-serif;
}

div#footer {
  font-family: sans-serif;
  font-size: small;
  border-top: 2px solid silver;
  padding-top: 0.5em;
  margin-top: 4.0em;
}
div#footer-text {
  float: left;
  padding-bottom: 0.5em;
}
div#footer-badges {
  float: right;
  padding-bottom: 0.5em;
}

div#preamble {
  margin-top: 1.5em;
  margin-bottom: 1.5em;
}
div.tableblock, div.imageblock, div.exampleblock, div.verseblock,
div.quoteblock, div.literalblock, div.listingblock, div.sidebarblock,
div.admonitionblock {
  margin-top: 1.0em;
  margin-bottom: 1.5em;
}
div.admonitionblock {
  margin-top: 2.0em;
  margin-bottom: 2.0em;
  margin-right: 10%;
  color: #606060;
}

div.content { /* Block element content. */
  padding: 0;
}

/* Block element titles. */
div.title, caption.title {
  color: #527bbd;
  font-family: sans-serif;
  font-weight: bold;
  text-align: left;
  margin-top: 1.0em;
  margin-bottom: 0.5em;
}
div.title + * {
  margin-top: 0;
}

td div.title:first-child {
  margin-top: 0.0em;
}
div.content div.title:first-child {
  margin-top: 0.0em;
}
div.content + div.title {
  margin-top: 0.0em;
}

div.sidebarblock > div.content {
  background: #ffffee;
  border: 1px solid silver;
  padding: 0.5em;
}

div.listingblock > div.content {
  border: 1px solid silver;
  background: #f4f4f4;
  padding: 0.5em;
}

div.quoteblock, div.verseblock {
  padding-left: 1.0em;
  margin-left: 1.0em;
  margin-right: 10%;
  border-left: 5px solid #dddddd;
  color: #777777;
}

div.quoteblock > div.attribution {
  padding-top: 0.5em;
  text-align: right;
}

div.verseblock > div.content {
  white-space: pre;
}
div.verseblock > div.attribution {
  padding-top: 0.75em;
  text-align: left;
}
/* DEPRECATED: Pre version 8.2.7 verse style literal block. */
div.verseblock + div.attribution {
  text-align: left;
}

div.admonitionblock .icon {
  vertical-align: top;
  font-size: 1.1em;
  font-weight: bold;
  text-decoration: underline;
  color: #527bbd;
  padding-right: 0.5em;
}
div.admonitionblock td.content {
  padding-left: 0.5em;
  border-left: 3px solid #dddddd;
}

div.exampleblock > div.content {
  border-left: 3px solid #dddddd;
  padding-left: 0.5em;
}

div.imageblock div.content { padding-left: 0; }
span.image img { border-style: none; }
a.image:visited { color: white; }

dl {
  margin-top: 0.8em;
  margin-bottom: 0.8em;
}
dt {
  margin-top: 0.5em;
  margin-bottom: 0;
  font-style: normal;
  color: navy;
}
dd > *:first-child {
  margin-top: 0.1em;
}

ul, ol {
    list-style-position: outside;
}
ol.arabic {
  list-style-type: decimal;
}
ol.loweralpha {
  list-style-type: lower-alpha;
}
ol.upperalpha {
  list-style-type: upper-alpha;
}
ol.lowerroman {
  list-style-type: lower-roman;
}
ol.upperroman {
  list-style-type: upper-roman;
}

div.compact ul, div.compact ol,
div.compact p, div.compact p,
div.compact div, div.compact div {
  margin-top: 0.1em;
  margin-bottom: 0.1em;
}

div.tableblock > table {
  border: 3px solid #527bbd;
}
thead, p.table.header {
  font-family: sans-serif;
  font-weight: bold;
}
tfoot {
  font-weight: bold;
}
td > div.verse {
  white-space: pre;
}
p.table {
  margin-top: 0;
}
/* Because the table frame attribute is overriden by CSS in most browsers. */
div.tableblock > table[frame="void"] {
  border-style: none;
}
div.tableblock > table[frame="hsides"] {
  border-left-style: none;
  border-right-style: none;
}
div.tableblock > table[frame="vsides"] {
  border-top-style: none;
  border-bottom-style: none;
}


div.hdlist {
  margin-top: 0.8em;
  margin-bottom: 0.8em;
}
div.hdlist tr {
  padding-bottom: 15px;
}
dt.hdlist1.strong, td.hdlist1.strong {
  font-weight: bold;
}
td.hdlist1 {
  vertical-align: top;
  font-style: normal;
  padding-right: 0.8em;
  color: navy;
}
td.hdlist2 {
  vertical-align: top;
}
div.hdlist.compact tr {
  margin: 0;
  padding-bottom: 0;
}

.comment {
  background: yellow;
}

.footnote, .footnoteref {
  font-size: 0.8em;
}

span.footnote, span.footnoteref {
  vertical-align: super;
}

#footnotes {
  margin: 20px 0 20px 0;
  padding: 7px 0 0 0;
}

#footnotes div.footnote {
  margin: 0 0 5px 0;
}

#footnotes hr {
  border: none;
  border-top: 1px solid silver;
  height: 1px;
  text-align: left;
  margin-left: 0;
  width: 20%;
  min-width: 100px;
}


@media print {
  div#footer-badges { display: none; }
}

div#toc {
  margin-bottom: 2.5em;
}

div#toctitle {
  color: #527bbd;
  font-family: sans-serif;
  font-size: 1.1em;
  font-weight: bold;
  margin-top: 1.0em;
  margin-bottom: 0.1em;
}

div.toclevel1, div.toclevel2, div.toclevel3, div.toclevel4 {
  margin-top: 0;
  margin-bottom: 0;
}
div.toclevel2 {
  margin-left: 2em;
  font-size: 0.9em;
}
div.toclevel3 {
  margin-left: 4em;
  font-size: 0.9em;
}
div.toclevel4 {
  margin-left: 6em;
  font-size: 0.9em;
}
/* Workarounds for IE6's broken and incomplete CSS2. */

div.sidebar-content {
  background: #ffffee;
  border: 1px solid silver;
  padding: 0.5em;
}
div.sidebar-title, div.image-title {
  color: #527bbd;
  font-family: sans-serif;
  font-weight: bold;
  margin-top: 0.0em;
  margin-bottom: 0.5em;
}

div.listingblock div.content {
  border: 1px solid silver;
  background: #f4f4f4;
  padding: 0.5em;
}

div.quoteblock-attribution {
  padding-top: 0.5em;
  text-align: right;
}

div.verseblock-content {
  white-space: pre;
}
div.verseblock-attribution {
  padding-top: 0.75em;
  text-align: left;
}

div.exampleblock-content {
  border-left: 3px solid #dddddd;
  padding-left: 0.5em;
}

/* IE6 sets dynamically generated links as visited. */
div#toc a:visited { color: blue; }
</style>
<script type="text/javascript">
/*<![CDATA[*/
window.onload = function(){asciidoc.footnotes(); asciidoc.toc(2);}
var asciidoc = {  // Namespace.

/////////////////////////////////////////////////////////////////////
// Table Of Contents generator
/////////////////////////////////////////////////////////////////////

/* Author: Mihai Bazon, September 2002
 * http://students.infoiasi.ro/~mishoo
 *
 * Table Of Content generator
 * Version: 0.4
 *
 * Feel free to use this script under the terms of the GNU General Public
 * License, as long as you do not remove or alter this notice.
 */

 /* modified by Troy D. Hanson, September 2006. License: GPL */
 /* modified by Stuart Rackham, 2006, 2009. License: GPL */

// toclevels = 1..4.
toc: function (toclevels) {

  function getText(el) {
    var text = "";
    for (var i = el.firstChild; i != null; i = i.nextSibling) {
      if (i.nodeType == 3 /* Node.TEXT_NODE */) // IE doesn't speak constants.
        text += i.data;
      else if (i.firstChild != null)
        text += getText(i);
    }
    return text;
  }

  function TocEntry(el, text, toclevel) {
    this.element = el;
    this.text = text;
    this.toclevel = toclevel;
  }

  function tocEntries(el, toclevels) {
    var result = new Array;
    var re = new RegExp('[hH]([2-'+(toclevels+1)+'])');
    // Function that scans the DOM tree for header elements (the DOM2
    // nodeIterator API would be a better technique but not supported by all
    // browsers).
    var iterate = function (el) {
      for (var i = el.firstChild; i != null; i = i.nextSibling) {
        if (i.nodeType == 1 /* Node.ELEMENT_NODE */) {
          var mo = re.exec(i.tagName);
          if (mo && (i.getAttribute("class") || i.getAttribute("className")) != "float") {
            result[result.length] = new TocEntry(i, getText(i), mo[1]-1);
          }
          iterate(i);
        }
      }
    }
    iterate(el);
    return result;
  }

  var toc = document.getElementById("toc");
  var entries = tocEntries(document.getElementById("content"), toclevels);
  for (var i = 0; i < entries.length; ++i) {
    var entry = entries[i];
    if (entry.element.id == "")
      entry.element.id = "_toc_" + i;
    var a = document.createElement("a");
    a.href = "#" + entry.element.id;
    a.appendChild(document.createTextNode(entry.text));
    var div = document.createElement("div");
    div.appendChild(a);
    div.className = "toclevel" + entry.toclevel;
    toc.appendChild(div);
  }
  if (entries.length == 0)
    toc.parentNode.removeChild(toc);
},


/////////////////////////////////////////////////////////////////////
// Footnotes generator
/////////////////////////////////////////////////////////////////////

/* Based on footnote generation code from:
 * http://www.brandspankingnew.net/archive/2005/07/format_footnote.html
 */

footnotes: function () {
  var cont = document.getElementById("content");
  var noteholder = document.getElementById("footnotes");
  var spans = cont.getElementsByTagName("span");
  var refs = {};
  var n = 0;
  for (i=0; i<spans.length; i++) {
    if (spans[i].className == "footnote") {
      n++;
      // Use [\s\S] in place of . so multi-line matches work.
      // Because JavaScript has no s (dotall) regex flag.
      note = spans[i].innerHTML.match(/\s*\[([\s\S]*)]\s*/)[1];
      noteholder.innerHTML +=
        "<div class='footnote' id='_footnote_" + n + "'>" +
        "<a href='#_footnoteref_" + n + "' title='Return to text'>" +
        n + "</a>. " + note + "</div>";
      spans[i].innerHTML =
        "[<a id='_footnoteref_" + n + "' href='#_footnote_" + n +
        "' title='View footnote' class='footnote'>" + n + "</a>]";
      var id =spans[i].getAttribute("id");
      if (id != null) refs["#"+id] = n;
    }
  }
  if (n == 0)
    noteholder.parentNode.removeChild(noteholder);
  else {
    // Process footnoterefs.
    for (i=0; i<spans.length; i++) {
      if (spans[i].className == "footnoteref") {
        var href = spans[i].getElementsByTagName("a")[0].getAttribute("href");
        href = href.match(/#.*/)[0];  // Because IE return full URL.
        n = refs[href];
        spans[i].innerHTML =
          "[<a href='#_footnote_" + n +
          "' title='View footnote' class='footnote'>" + n + "</a>]";
      }
    }
  }
}

}
/*]]>*/
</script>
</head>
<body>
<div id="header">
<h1>Gerrit Code Review - Superprojects subscribed to submodules updates</h1>
<span id="revnumber">version 2.3</span>
<div id="toc">
  <div id="toctitle">Table of Contents</div>
  <noscript><p><b>JavaScript must be enabled in your browser to display the table of contents.</b></p></noscript>
</div>
</div>
<div id="content">
<h2 id="_description">Description</h2>
<div class="sectionbody">
<div class="paragraph"><p>Gerrit supports a custom git superproject feature for tracking submodules.
This feature is useful for automatic updates on superprojects whenever
a change is merged on tracked submodules. To take advantage of this
feature, one should add submodule(s) to a local working copy of a
superproject, edit the created .gitmodules configuration file to
have a branch field on each submodule section with the value of the
submodule branch it is subscribing to, commit the changes, push and
merge the commit.</p></div>
<div class="paragraph"><p>When a commit is merged to a project, the commit content is scanned
to identify if it registers git submodules (if the commit registers
any gitlinks and .gitmodules file with required info) and if so,
a new submodule subscription is registered.</p></div>
<div class="paragraph"><p>When a new commit of a registered submodule is merged, gerrit
automatically updates the subscribers to the submodule with a new
commit having the updated gitlinks.</p></div>
</div>
<h2 id="_git_submodules_overview">Git Submodules Overview</h2>
<div class="sectionbody">
<div class="paragraph"><p>It is a git feature that allows an external repository to be
attached inside a repository at a specific path. The objective here
is to provide a brief overview, further details can be found
in the official git submodule command documentation.</p></div>
<div class="paragraph"><p>Imagine a repository called <em>super</em> and another one called <em>a</em>.
Also consider <em>a</em> available in a running gerrit instance on "server".
With this feature, one could attach <em>a</em> inside of <em>super</em> repository
at path <em>a</em> by executing the following command when being inside
<em>super</em>:</p></div>
<div class="exampleblock">
<div class="exampleblock-content">
<div class="paragraph"><p>git submodule add ssh://server/a a</p></div>
</div></div>
<div class="paragraph"><p>Still considering the above example, after its execution notice that
inside the local repository <em>super</em> the <em>a</em> folder is considered a
gitlink to the external repository <em>a</em>. Also notice a file called
.gitmodules is created (it is a config file containing the
subscription of <em>a</em>). To provide the sha-1 each gitlink points to in
the external repository, one should use the command:</p></div>
<div class="exampleblock">
<div class="exampleblock-content">
<div class="paragraph"><p>git submodule status</p></div>
</div></div>
<div class="paragraph"><p>In the example provided, if <em>a</em> is updated and <em>super</em> is supposed
to see the latest sha-1 (considering here <em>a</em> has only the master
branch), one should then commit the modified gitlink for <em>a</em> in
the <em>super</em> project. Actually it would not even need to be an
external update, one could move to <em>a</em> folder (insider <em>super</em>),
modify its content, commit, then move back to <em>super</em> and
commit the modified gitlink for <em>a</em>.</p></div>
</div>
<h2 id="_creating_a_new_subscription">Creating a New Subscription</h2>
<div class="sectionbody">
<h3 id="_defining_the_submodule_branch">Defining the Submodule Branch</h3><div style="clear:left"></div>
<div class="paragraph"><p>This is required because Submodule subscription is actually the
subscription of a submodule project and one of its branches for
a branch of a super project.</p></div>
<div class="paragraph"><p>Since it manages subscriptions in the branch scope, we could have
a scenario having a project called <em>super</em> having a branch <em>integration</em>
subscribed to a project called <em>a</em> in branch <em>integration</em>, and also
having the same <em>super</em> project but in branch <em>dev</em> subscribed to the <em>a</em>
project in a branch called <em>local-dev</em>.</p></div>
<div class="paragraph"><p>After adding the git submodule to a super project, one should edit
the .gitmodules file to add a branch field to each submodule
section which is supposed to be subscribed.</p></div>
<div class="paragraph"><p>The branch field is not filled by the git submodule command. Its value
should indicate the branch of a submodule project that when updated
will trigger automatic update of its registered gitlink.</p></div>
<div class="paragraph"><p>The branch value could be <em>.</em> if the submodule project branch
has the same name as the destination branch of the commit having
gitlinks/.gitmodules file.</p></div>
<div class="paragraph"><p>The branch field of a submodule section is a custom git submodule
feature for gerrit use. One should always be sure to fill it in
editing .gitmodules file after adding submodules to a super project,
if it is the intention to make use of the gerrit feature introduced here.</p></div>
<div class="paragraph"><p>Any git submodules which are added and not have the branch field
available in the .gitmodules file will not be subscribed by gerrit
to automatically update the superproject.</p></div>
<h3 id="_detecting_and_subscribing_submodules">Detecting and Subscribing Submodules</h3><div style="clear:left"></div>
<div class="paragraph"><p>Whenever a commit is merged to a project, its content is scanned
to identify if it registers any submodules (if the commit contains new
gitlinks and a .gitmodules file with all required info) and if so,
a new submodule subscription is registered.</p></div>
</div>
<h2 id="_automatic_update_of_superprojects">Automatic Update of Superprojects</h2>
<div class="sectionbody">
<div class="paragraph"><p>After a superproject is subscribed to a submodule, it is not
required to push/merge commits to this superproject to update the
gitlink to the submodule.</p></div>
<div class="paragraph"><p>Whenever a commit is merged in a submodule, its subscribed superproject
is updated.</p></div>
<div class="paragraph"><p>Imagine a superproject called <em>super</em> having a branch called <em>dev</em>
having subscribed to a submodule <em>a</em> on a branch <em>dev-of-a</em>. When a commit
is merged in branch <em>dev-of-a</em> of <em>a</em> project, gerrit automatically
creates a new commit on branch <em>dev</em> of <em>super</em> updating the gitlink
to point to the just merged commit.</p></div>
<h3 id="_canonical_web_url">Canonical Web Url</h3><div style="clear:left"></div>
<div class="paragraph"><p>Gerrit will automatically update only the superprojects that added
the submodules of urls of the running server (the one described in
the canonical web url value in gerrit configuration file).</p></div>
<div class="paragraph"><p>The Gerrit instance administrator group should always certify to
provide the canonical web url value in its configuration file. Users
should certify to use the url value of the running gerrit instance to
add/subscribe submodules.</p></div>
</div>
<h2 id="_removing_subscriptions">Removing Subscriptions</h2>
<div class="sectionbody">
<div class="paragraph"><p>If one has added a submodule subscription and drops it, it is
required to merge a commit updating the subscribed super
project/branch to remove the gitlink and the submodule section
of the .gitmodules file.</p></div>
</div>
<hr style="
  height: 2px;
  color: silver;
  margin-top: 1.2em;
  margin-bottom: 0.5em;
">
<div class="paragraph"><p>Part of <a href="index.html">Gerrit Code Review</a></p></div>
</div>
<div id="footnotes"><hr /></div>
<div id="footer">
<div id="footer-text">
Version 2.3<br />
Last updated 2012-03-19 10:06:38 MDT
</div>
</div>
</body>
</html>
